package tech.cn.note.word.fun;

import java.lang.reflect.Field;
import java.math.BigDecimal;
import java.util.Collection;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.stream.Collectors;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.text.CharSequenceUtil;
import cn.hutool.core.util.ArrayUtil;
import cn.hutool.core.util.StrUtil;
import com.deepoove.poi.render.compute.RenderDataCompute;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.google.common.collect.Lists;

import org.springframework.stereotype.Service;

import static cn.hutool.core.text.CharSequenceUtil.NULL;

@Service
public class BeanToList implements RenderFunction {

    @Override
    public String doCalculate(String[] fields, RenderDataCompute renderDataCompute) {
        if (fields == null || fields.length < 2 || StrUtil.hasBlank(fields[0], fields[1])) {
            return "";
        }
        String value1 = fields[0];
        String value2 = fields[1];

        Object data = renderDataCompute.compute(value1);
        String field = (String) renderDataCompute.compute(value2);
        String conjunction = Optional.ofNullable(ArrayUtil.get(fields, 2))
                .map(v -> (String) renderDataCompute.compute((String) v))
                .orElse(",");

        List<String> list = obj2List(data, field);
        if (CollUtil.isEmpty(list)) {
            return null;
        } else {
            return CollUtil.join(list, conjunction);
        }
    }


    public static List<String> obj2List(Object data, String field) {
        List<String> list = Lists.newArrayList();
        // data为list
        if (data instanceof Collection) {
            list = ((List<?>) data).stream().map(v -> {
                try {
                    if (v instanceof Map) {
                        Map<String, Object> map = (Map<String, Object>) v;
                        Object mapField = map.get(field);
                        return mapField instanceof BigDecimal
                                ? ((BigDecimal) mapField).toPlainString()
                                : String.valueOf(mapField);
                    } else {
                        Field declaredField = v.getClass().getDeclaredField(field);
                        declaredField.setAccessible(true);
                        return declaredField.get(v).toString();
                    }
                } catch (NoSuchFieldException | IllegalAccessException ignored) {
                    // 不打日志了 避免刷屏
                    return null;
                }
            }).collect(Collectors.toList());
        } else if (data instanceof String) {
            // data为字符串（由list转）
            ObjectMapper objectMapper = new ObjectMapper();
            try {
                List<Map<String, Object>> mapList = objectMapper.readValue(data.toString(),
                        new TypeReference<List<Map<String, Object>>>() {
                        });
                list = mapList.stream()
                        .filter(map -> map.containsKey(field))
                        .map(map -> map.get(field) instanceof BigDecimal
                                ? ((BigDecimal) map.get(field)).toPlainString()
                                : String.valueOf(map.get(field))
                        )
                        .collect(Collectors.toList());
            } catch (JsonProcessingException e) {
                // 不打日志了 避免刷屏
            }
        }
        return list.stream().filter(v -> CharSequenceUtil.isNotBlank(v) && !NULL.equals(v)).collect(Collectors.toList());
    }

}
